#ifndef PARTICLESOURCEFACTORY_H
#define PARTICLESOURCEFACTORY_H

#include "ParticleSource1D_Emit.h"
#include "ParticleSource1D_Load.h"
#include "ParticleSource2D_Load.h"
#include "ParticleSource3D_Load.h"

#include <string>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <ostream>
#include <sstream>
using namespace std;



class ParticleSourceFactory {

public:

	//Reads the input file and creates the PSI objects accordingly
    static vector<ParticleSource*> create(PicParams* params_, ParallelMPI* pmpi_, PhysicalField* fields_, vector<Species*>* vecSpecies_)
	{
	    vector<ParticleSource*> vecParticleSource;

        for (int i_ps = 0; i_ps < params_->particle_source_param.size(); i_ps++)
		{
            ParticleSourceParameter ps_param_;
            ps_param_ = params_->particle_source_param[i_ps];

            if(params_->geometry == "1d3v" && ps_param_.ps_type == "emit")
			{
                vecParticleSource.push_back(new ParticleSource1D_Emit(params_, pmpi_, fields_, vecSpecies_, ps_param_));
			}

            else if(params_->geometry == "1d3v" && ps_param_.ps_type == "load")
			{
                vecParticleSource.push_back(new ParticleSource1D_Load(params_, pmpi_, fields_, vecSpecies_, ps_param_));
			}

            else if(params_->geometry == "2d3v" && ps_param_.ps_type == "load")
			{
                vecParticleSource.push_back(new ParticleSource2D_Load(params_, pmpi_, fields_, vecSpecies_, ps_param_));
			}

            else if(params_->geometry == "3d3v" && ps_param_.ps_type == "load")
			{
                vecParticleSource.push_back(new ParticleSource3D_Load(params_, pmpi_, fields_, vecSpecies_, ps_param_));
			}

            else
            {
                log_error<<"no particle source type match: "<<ps_param_.ps_type;
			}
	    }

	    return vecParticleSource;
	};

};

#endif
